package controller

import (
	"ci-control-backend/common/db"
	"ci-control-backend/common/httpx"
	"ci-control-backend/common/tasks"
	"ci-control-backend/model"
	"ci-control-backend/tools"
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
)

type PlanController struct{}

// NewPlan 添加构建计划
func (*PlanController) NewPlan(ctx *httpx.Context) any {
	var req struct {
		PlanName       string `json:"plan_name"`
		PipelineScript string `json:"pipeline_script"`
		ExecHosts      string `json:"exec_hosts"`
	}

	err := ctx.ShouldBindJSON(&req)
	if err != nil {
		return errors.WithStack(err)
	}

	if req.PlanName == "" {
		return errors.New("计划名称不可为空")
	}
	if req.PipelineScript == "" {
		return errors.New("流水线不可为空")
	}
	if req.ExecHosts == "" {
		return errors.New("执行主机组不可为空")
	}

	keys, _ := tools.RandomStr(64)
	plan := &model.Plan{
		PlanName:       req.PlanName,
		PipelineScript: req.PipelineScript,
		ExecHosts:      req.ExecHosts,
		CallKeys:       keys,
	}
	if _, err := plan.Insert(); err != nil {
		return errors.WithStack(err)
	}

	return "创建计划成功"
}

// DelPlan 删除计划
func (*PlanController) DelPlan(ctx *httpx.Context) any {
	id := ctx.ParamUint("id")
	plan, err := model.GetPlanByID(id)
	if err != nil {
		return errors.WithStack(err)
	}
	if plan == nil {
		return errors.Errorf("不存在id=%v的计划", id)
	}
	if _, err := plan.Delete(); err != nil {
		return errors.WithStack(err)
	}
	return "删除成功"
}

// UpdatePlan 删除计划
func (*PlanController) UpdatePlan(ctx *httpx.Context) any {
	id := ctx.ParamUint("id")
	plan, err := model.GetPlanByID(id)
	if err != nil {
		return errors.WithStack(err)
	}
	if plan == nil {
		return errors.Errorf("不存在id=%v的计划", id)
	}

	var req struct {
		PlanName       string `json:"plan_name"`
		PipelineScript string `json:"pipeline_script"`
		ExecHosts      string `json:"exec_hosts"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		return errors.WithStack(err)
	}

	if req.PlanName == "" && req.PipelineScript == "" && req.ExecHosts == "" {
		return errors.New("参数错误")
	}

	if req.PlanName != "" {
		plan.PlanName = req.PlanName
	}
	if req.PipelineScript != "" {
		plan.PipelineScript = req.PipelineScript
	}
	if req.ExecHosts != "" {
		plan.ExecHosts = req.ExecHosts
	}

	if _, err := plan.Update(); err != nil {
		return errors.WithStack(err)
	}

	return "修改成功"
}

// GetPlanList 获取计划列表
func (*PlanController) GetPlanList(ctx *httpx.Context) any {
	var page, pageSize int
	err := ctx.MultiQuery(gin.H{
		"page":     &page,
		"pageSize": &pageSize,
	})
	if err != nil {
		return err
	}

	// 分页查询
	pageable := db.QueryPage(&model.Plan{})
	pageResult, err := pageable.PageParam(page, pageSize).Exec()
	if err != nil {
		return err
	}
	for _, plan := range pageResult.PageData {
		plan.CallKeys = ""
	}
	return pageResult
}

// GetHookKeys 获取hook密钥
func (*PlanController) GetHookKeys(ctx *httpx.Context) any {
	var id uint
	if err := ctx.Query("id", &id); err != nil {
		return errors.WithStack(err)
	}

	if id == 0 {
		return errors.New("id不允许为空")
	}

	plan, err := model.GetPlanByID(id)
	if err != nil {
		return errors.WithStack(err)
	}
	if plan == nil {
		return errors.Errorf("不存在id=%v的计划", id)
	}

	return gin.H{"key": plan.CallKeys}
}

// StartBuild 开始构建
func (*PlanController) StartBuild(ctx *httpx.Context) any {
	var id uint
	if err := ctx.Query("id", &id); err != nil {
		return errors.WithStack(err)
	}

	if id == 0 {
		return errors.New("id不允许为空")
	}

	plan, err := model.GetPlanByID(id)
	if err != nil {
		return errors.WithStack(err)
	}
	if plan == nil {
		return errors.Errorf("不存在id=%v的计划", id)
	}

	// 将计划添加到任务队列中
	if err := tasks.AddTask(plan); err != nil {
		return errors.WithStack(err)
	}

	return "任务已开始"
}

// StartBuildHook 以WebHook方式启动构建
func (*PlanController) StartBuildHook(ctx *httpx.Context) any {
	key := ctx.Param("key")

	if key == "" {
		return errors.New("key不允许为空")
	}

	plan, err := model.GetPlanByCallKeys(key)
	if err != nil {
		return errors.WithStack(err)
	}
	if plan == nil {
		return errors.Errorf("不存在keys=%v的计划", key)
	}

	if err := tasks.AddTask(plan); err != nil {
		return errors.WithStack(err)
	}

	return "任务已开始"
}
